/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package cz.dusa.switco;

import java.util.ArrayList;
import java.util.List;

/**
 * Interface defining convex cost function. If you want to use your own convex cost function,
 * implement this interface. For example see {@link DefaultConvexCostFunction}
 * @author vdusa
 */
public abstract class ConvexCostFunction {
    private double timeShift = 0;
    private List<ConvexCostFunctionListener> convexCostFunctionListeners = new ArrayList<ConvexCostFunctionListener>();
    
    /**
     * This method must implement evaluation of convex cost function.
     *
     * @param t time point in which the function should be evaluated
     * @return value of the cost function in the time point t
     * @throws cz.dusa.pertconvd.EvaluationException
     */
    public abstract Double evaluate(double t) throws cz.dusa.switco.EvaluationException;
    
    /**
     * sets the time shift of the function. The evaluation evaluate(t) will be later
     * made with respect to this time shift as evaluate(t+timeShift).
     *
     * Do not forget to inform ConvexCostFuctionSum about this change. See
     * {@link DefaultConvexCostFunction#setTimeShift(double)} for an example.
     * @param timeShift
     */
    public void setTimeShift(double timeShift){
        this.timeShift = timeShift;

        for(ConvexCostFunctionListener convexCostFunctionListener: convexCostFunctionListeners){
            convexCostFunctionListener.AfterConvexCostFunctionChanged();
        }
    }

     /**
     * For more information see {@link #setTimeShift(double)}
     * @return time shift of the convex function
     */
    public double getTimeShift(){
        return timeShift;
    }

    /**
     * If the cost function is changed (e.g. the formula or the time shift is changed), we must
     * inform all listeners about it.
     * @param convexCostFunctionListener
     */
    public void addConvexCostFunctionListener(ConvexCostFunctionListener convexCostFunctionListener) {
        convexCostFunctionListeners.add(convexCostFunctionListener);
    }

     /**
     * If the cost function is changed (e.g. the formula or the time shift is changed), we must
     * inform all listeners about it.
     * @param convexCostFunctionListener
     */
    public void removeConvexCostFunctionListener(ConvexCostFunctionListener convexCostFunctionListener) {
        convexCostFunctionListeners.remove(convexCostFunctionListener);
    }
}
